package com.ruoyi.common.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

/**
 * 签名计算工具类
 *
 * @author ruoyi
 * @date 2024-01-01
 */
public class SignatureUtils {
    private static final Logger logger = LoggerFactory.getLogger(SignatureUtils.class);
    /**
     * 校验签名
     *
     * @param signature 加密签名
     * @param timestamp 时间戳
     * @param nonce 随机数
     * @param token 自己配置的 token
     * @return 验证结果
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce, String token) {
        // 1. 将token、timestamp、nonce三个参数进行字典序排序
        String[] array = {token, timestamp, nonce};
        Arrays.sort(array);

        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        StringBuilder content = new StringBuilder();
        for (String item : array) {
            content.append(item);
        }

        // 3. 使用SHA1算法加密
        String tempStr = sha1(content.toString());
        logger.info("tempStr:  {}",tempStr);
        // 4. 将sha1加密后的字符串可与signature对比，标识该请求来源于微信
        return tempStr.equals(signature);
    }

    /**
     * SHA1加密
     *
     * @param str 待加密字符串
     * @return 加密后的字符串
     */
    private static String sha1(String str){
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(str.getBytes());
            return byteArrayToHexString(digest);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }

    }
    /**
     * 字节数组转十六进制字符串
     * @param bytes 字节数组
     * @return 十六进制字符串
     */
    private static String byteArrayToHexString(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(byteToHexStr(b));
        }
        return result.toString();
    }
    /**
     * 单个字节转十六进制字符串
     * @param mByte 字节
     * @return 十六进制字符串
     */
    public static String byteToHexStr(byte mByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        return new String(tempArr);
    }
}
